/**
 * Copyright (c) 2015-2017, Javen Zhou  (javen205@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */

package com.javen.weixin.controller;

import java.util.ArrayList;
import java.util.List;

import com.javen.weixin.Interceptor.ConfigInterceptor;
import com.javen.weixin.common.model.Config;
import com.javen.weixin.common.model.Keyword;
import com.javen.weixin.common.model.Material;
import com.javen.weixin.common.model.Qrcode;
import com.javen.weixin.common.model.Replymessage;
import com.javen.weixin.common.model.Submsg;
import com.javen.weixin.common.model.User;
import com.javen.weixin.kit.URLCodeKit;
import com.javen.weixin.service.ConfigService;
import com.javen.weixin.service.KeyWordService;
import com.javen.weixin.service.MaterialService;
import com.javen.weixin.service.QrcodeService;
import com.javen.weixin.service.ReplyMessageService;
import com.javen.weixin.service.SubMsgService;
import com.javen.weixin.service.WxUserService;
import com.javen.weixin.utils.RedPackUtil;
import com.jfinal.aop.Before;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.CustomServiceApi;
import com.jfinal.weixin.sdk.api.CustomServiceApi.Articles;
import com.jfinal.weixin.sdk.api.UserApi;
import com.jfinal.weixin.sdk.jfinal.MsgControllerAdapter;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.msg.in.InTextMsg;
import com.jfinal.weixin.sdk.msg.in.event.InFollowEvent;
import com.jfinal.weixin.sdk.msg.in.event.InLocationEvent;
import com.jfinal.weixin.sdk.msg.in.event.InMenuEvent;
import com.jfinal.weixin.sdk.msg.in.event.InQrCodeEvent;
import com.jfinal.weixin.sdk.msg.out.News;
import com.jfinal.weixin.sdk.msg.out.OutImageMsg;
import com.jfinal.weixin.sdk.msg.out.OutNewsMsg;
import com.jfinal.weixin.sdk.msg.out.OutTextMsg;

/**
 * @author Javen 2017年6月11日
 */
@Before(ConfigInterceptor.class)
public class WeiXinMsgController extends MsgControllerAdapter {

	static Log logger = Log.getLog(WeiXinMsgController.class);
	private static final String helpStr = "\t你的品位不错哦  么么哒 -By Javen。";

	static ConfigService cs = ConfigService.me;
	static KeyWordService kws = KeyWordService.me;
	static SubMsgService subs = SubMsgService.me;
	static MaterialService materials = MaterialService.me;
	static WxUserService wxus = WxUserService.me;
	static ReplyMessageService rmService = ReplyMessageService.me;
	static QrcodeService qrcodeService = QrcodeService.me;
	/**
	 * 接收文本消息事件
	 */
	@Override
	protected void processInTextMsg(InTextMsg inTextMsg) {
		String msgContent = inTextMsg.getContent().trim();
		final String openId = inTextMsg.getFromUserName();
		 String rmid = getPara("rmid");
//		final Config config = (Config) getSession().getAttribute("config");
		final Config config = cs.getConfigByRmid(rmid);
		int appType = config.getAppType();
		logger.info(config.toJson());
		List<Keyword> keywords = kws.getKeyWord(config.getAppId(), msgContent);
		
logger.info("keywords>" + JsonKit.toJson(keywords));
		if (null != keywords && keywords.size() > 0) {
			int size = keywords.size();
			Keyword keyword = keywords.get(0);
			
			//异步发送其他的消息
			if (size >= 1 && (appType == 1 || appType == 3 || appType == 5)) {
				for (int i = 1; i < size; i++) {
					Keyword asyncKeyword = keywords.get(i);
					Integer async = asyncKeyword.getAsync();
					if (async == 1) {
						replyMessage(1, true, config, openId, asyncKeyword,appType);
					}
				}
			}
			
			// 被动回复消息
			replyMessage(1,false, config,openId, keyword,appType);
		}
		
		if (msgContent.equals("红包")) {
			new Thread(new Runnable() {
				public void run() {
					logger.info("是发红包的时候了...");
					RedPackUtil.sendRedPack(config, 1, openId, IpKit.getRealIp(getRequest()));
				}
			}).start();
			renderNull();
			return;
		}
		renderOutTextMsg(msgContent);
	}

	/**
	 * 关注/取消关注事件
	 */
	@Override
	protected void processInFollowEvent(final InFollowEvent inFollowEvent) {
		try {
			if (InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())) {
				final Config config = (Config) getSession().getAttribute("config");
				// 公众号的类型 1=测试号,2=订阅号,3=认证订阅号,4=服务号,5=认证服务号,6=企业号,7=认证企业号
				final Integer appType = config.getAppType();
				final String openId = inFollowEvent.getFromUserName();
				final String appId = config.getAppId();
logger.info("关注：" + openId);
				if (appType == 1 || appType == 3 || appType == 5) {
					// 获取用户基本信息(UnionID机制)
					ApiResult userInfo = UserApi.getUserInfo(openId);
					if (userInfo.isSucceed()) {
						final User user = wxus.toSave(appId, userInfo);
						if (null != user) {
							new Thread(new Runnable() {
								@Override
								public void run() {
									// 客服接口发送异步消息
									StringBuffer sbf = new StringBuffer();
									sbf.append("欢迎").append("【").append(URLCodeKit.decode(user.getNickName())).append("】")
											.append("关注。");
									CustomServiceApi.sendText(openId, sbf.toString());
								}
							}).start();
						}
					}
				}
				
				// 关注回复消息集合
				List<Submsg> submsgList = subs.getSubMsgByAppId(config.getAppId());
logger.info("submsg：" + JsonKit.toJson(submsgList));
				// 如果关注回复消息不为空
				if (null != submsgList && submsgList.size() > 0) {
					//取第一个submsg作为被动回复 其他的使用客服消息异步回复
					final Submsg submsg = submsgList.get(0);
					//判断是否有异步回复消息的权限
					if (submsgList.size()>= 1 &&(appType == 1 || appType == 3 || appType == 5)) {
			logger.info("有多条关注回复的消息");			
						//有多条关注回复的消息
						for (int i = 1; i < submsgList.size(); i++) {
							final Submsg asynSubmsg = submsgList.get(i);
							new Thread(new Runnable() {
								
								@Override
								public void run() {
									replyMessage(2, true, config, openId, asynSubmsg,appType);
								}
							}).start();
						}
					}
					
					// 被动回复消息
					replyMessage(2,false, config,openId, submsg,appType);
				}

				OutTextMsg outMsg = new OutTextMsg(inFollowEvent);
				outMsg.setContent(helpStr);
				render(outMsg);
			}
			// 如果为取消关注事件，将无法接收到传回的信息
			if (InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())) {
				logger.debug("取消关注：" + inFollowEvent.getFromUserName());
				renderNull();
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

	}

	/**
	 * 自定义菜单事件
	 */
	@Override
	protected void processInMenuEvent(InMenuEvent inMenuEvent) {
		StringBuffer sbf = new StringBuffer();
		sbf.append("事件类型：").append(inMenuEvent.getEvent()).append("\n").append("消息类型：").append(inMenuEvent.getMsgType())
				.append("\n")

				// sbf.append("扫码内容：").append(inMenuEvent.getScanCodeInfo().getScanResult()).append("\n")

				.append("openId：").append(inMenuEvent.getFromUserName()).append("\n").append("事件Key：")
				.append(inMenuEvent.getEventKey()).append("\n");
		renderOutTextMsg(sbf.toString());
	}

	@Override
	protected void processInQrCodeEvent(InQrCodeEvent inQrCodeEvent) {
		final Config config = (Config) getSession().getAttribute("config");
		// 公众号的类型 1=测试号,2=订阅号,3=认证订阅号,4=服务号,5=认证服务号,6=企业号,7=认证企业号
		final Integer appType = config.getAppType();
		final String openId = inQrCodeEvent.getFromUserName();
		final String appId = config.getAppId();
		final String ticket = inQrCodeEvent.getTicket();
		
		
		System.out.println("扫码.......");
		if (InQrCodeEvent.EVENT_INQRCODE_SUBSCRIBE.equals(inQrCodeEvent.getEvent())) {
			logger.debug("扫码未关注：" + openId);
			OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent);
			outMsg.setContent("感谢您的关注，二维码内容：" + inQrCodeEvent.getEventKey());
			render(outMsg);
		}
		if (InQrCodeEvent.EVENT_INQRCODE_SCAN.equals(inQrCodeEvent.getEvent())) {
			logger.debug("扫码已关注：" + openId);
			Qrcode qrcode = qrcodeService.getQrcodeByTicket(ticket, appId);
			if (null != qrcode) {
				String messageId = qrcode.getMessageId();
				if (StrKit.notBlank(messageId)) {
					String[] ids = messageId.split(",");
					List<Replymessage> list = rmService.getReplymessageByIds(ids, appId);
					if (null != list && list.size() > 0) {
						Replymessage replymessage = list.get(0);
						//判断是否有异步回复消息的权限
						if (list.size()>= 1 &&(appType == 1 || appType == 3 || appType == 5)) {
							//有多条关注回复的消息
							for (int i = 1; i < list.size(); i++) {
								final Replymessage asynReplymessage = list.get(i);
								new Thread(new Runnable() {
									
									@Override
									public void run() {
										replyMessage(3, true, config, openId, asynReplymessage,appType);
									}
								}).start();
							}
						}
						// 被动回复消息
						replyMessage(3, false, config, openId, replymessage,appType);
					}
				}
			}
		}
	}

	@Override
	protected void processInLocationEvent(InLocationEvent inLocationEvent) {
		logger.debug("发送地理位置事件：" + inLocationEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
		outMsg.setContent("地理位置是：" + inLocationEvent.getLatitude());
		render(outMsg);
	}

	public void renderOutTextMsg(String content) {
		OutTextMsg outMsg = new OutTextMsg(getInMsg());
		outMsg.setContent(content);
		render(outMsg);
	}
	
	public void renderOutImageMsg(String mediaId) {
		OutImageMsg outMsg = new OutImageMsg(getInMsg());
		outMsg.setMediaId(mediaId);
		render(outMsg);
	}

	/**
	 * 根据AppId 以及 文件key查询图文
	 * 
	 * @param appId
	 * @param article_key
	 * @param articleType  1为普通的图文回复   2为客服消息的图文回复
	 * @return
	 */
	public static Object getNews(String appId, String article_key, int articleType) {
		
		List<Material> list = materials.getMaterialBySKI(appId, article_key);
		logger.info("material list>" + JsonKit.toJson(list));
		if (null != list && list.size() > 0) {
			if (articleType == 1) {
				List<News> articles = new ArrayList<News>();
				for (Material material : list) {
					News news = new News();
					news.setTitle(material.getTitle());
					String url = material.getUrl();
					if (StrKit.notBlank(url)) {
						news.setUrl(url);
					} else {
						news.setUrl(PropKit.get("domain") + "/material/getById?id=" + material.getId());
					}
					news.setPicUrl(material.getImageUrl());
					news.setDescription(material.getDescribe());
					articles.add(news);
				}
				return articles;
			}else if (articleType == 2) {
				List<Articles> articles = new ArrayList<Articles>();
				for (Material material : list) {
					Articles article = new Articles();
					article.setTitle(material.getTitle());
					article.setDescription(material.getDescribe());
					article.setPicurl(material.getImageUrl());
					String url = material.getUrl();
					if (StrKit.notBlank(url)) {
						article.setUrl(url);
					} else {
						article.setUrl(PropKit.get("domain") + "/material/getById?id=" + material.getId());
					}
					
					articles.add(article);
				}
				return articles;
			}
		}
		return null;
	}
	
	/**
	 * 回复消息
	 * @param actionType 1 关键字回复 2 关注回复 3 回复消息
	 * @param isCustomMessage 是否是客服消息
	 * @param appId
	 * @param openId 
	 * @param object
	 * @param appType 公众号类型
	 */
	public void replyMessage(int actionType, boolean isCustomMessage,final Config config, final String openId, Object object, int appType){
		String content = null;
		String mediaId = null;
		String articleKey = null;
		int redpackId = 0;
		
		int messageType = 0;
		
		if (actionType == 1) {
			Keyword keyword = (Keyword) object;
			content = keyword.getContent();
			mediaId = keyword.getMediaId();
			messageType = keyword.getType();
			articleKey = content;
		}else if (actionType == 2) {
			Submsg submsg = (Submsg) object;
			content = submsg.getContent();
			mediaId = submsg.getMediaId();
			messageType = submsg.getType();
			articleKey = submsg.getArticleKey();
			redpackId = submsg.getRedpackId();
		}else if (actionType == 3) {
			Replymessage replymessage = (Replymessage) object;
			content = replymessage.getContent();
			mediaId = replymessage.getMediaId();
			messageType = replymessage.getType();
			articleKey = replymessage.getArticleKeyword();
			redpackId = replymessage.getRedpackId();
		}
		
		if (isCustomMessage) {
			//客服接口发现消息
			if (messageType == 1 ) {
				ApiResult sendText = CustomServiceApi.sendText(openId, content);
				System.out.println("异步发送文本:"+sendText.getJson());
				logger.info("异步发送文本:"+sendText.getJson());
			} else if (messageType == 2) {
				// 图文 通过文章的关键字查询回复的图文
				String key = articleKey.trim();
				logger.info("articleKey>" + key);
				@SuppressWarnings("unchecked")
				List<Articles> news = (List<Articles>) getNews(config.getAppId(), key ,2);
				ApiResult sendNews = CustomServiceApi.sendNews(openId, news);
				logger.info("异步发送图文:"+sendNews.getJson());
			} else if (messageType == 3) {
				ApiResult sendImage = CustomServiceApi.sendImage(openId, mediaId);
				logger.info("异步发送图片:"+sendImage.getJson());
			}
		}else {
			//被动回复消息
			if (messageType == 1) {
				renderOutTextMsg(content);
				return;
			} else if (messageType == 2) {
				// 通过关键字查询图文
				OutNewsMsg outMsg = new OutNewsMsg(getInMsg());
				@SuppressWarnings("unchecked")
				List<News> news = (List<News>) getNews(config.getAppId(), articleKey ,1);
				outMsg.setArticles(news);
				render(outMsg);
				return;
			}else if (messageType == 3) {
				// 图片
				renderOutImageMsg(mediaId);
				return;
			}else if (messageType == 4) {
				// 红包
				// 认证的服务号才有发红包的权限
				if (appType == 5) {
					final int readId = redpackId;
					// 异步判断是否需要发红包
					new Thread(new Runnable() {

						@Override
						public void run() {
							// 判断是否需要发红包
							logger.info("readpackId>" + readId);
							RedPackUtil.sendRedPack(config, readId, openId,
									IpKit.getRealIp(getRequest()));
						}
					}).start();
				}
				renderNull();
				return;
			}
		}
		
	}
}
